﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using SGLisp;
using PBMessage;
using GameUnit;
public class GameSceneTrigger
{
    public GameTrigger Trigger = new GameTrigger();

    public void DefineActions()
    {
       Context context = Trigger.ClojureContext;
       context.Define("create-starting-units",new FunctionNode( _Create_Starting_Unit));
       context.Define("create-actor",new FunctionNode(_create_actor));
       context.Define("play-anim",new FunctionNode(_play_anim));
        context.Define("play-anim-fade",new FunctionNode(_play_anim_fade));
       context.Define("revive-unit",new FunctionNode(_revive_unit));
       context.Define("unit-all",new FunctionNode(_unit_all));
       context.Define("opt-unit-attr",new FunctionNode(_opt_unit_attr));
       context.Define("unit-behavior-attr-value-cp",new FunctionNode(_unit_behavior_attr_value_cp));
        context.Define("unit-behavior-attr-value",new FunctionNode(_unit_behavior_attr_value));
    }

    ASTNode _unit_behavior_attr_value_cp(List<ASTNode> args, Context context) 
    {
        args = CoreFunction.EvalArgs(args,context);
        Unit unit = (Unit)((ObjectNode)args[0]).Val;
        string behaviorName = ((StringNode)args[1]).Val;
        string cpType = ((KeywordNode)args[2]).Val;
        ASTNode cpValue = args[3];
        BehaviorAttribute behaviorAttr = (BehaviorAttribute)unit.GetBehavior(behaviorName);
        switch (cpValue.NodeType) 
        {
            case ASTNode.ASTNodeType.NumberNode:
                NumberNode curNumerNode = ((NumberNode)cpValue);
                switch (curNumerNode.Type) 
                {
                    case  NumberNode.NumberType.INT:
                        switch (cpType) 
                        {
                            case ":=":
                                if ((int)behaviorAttr.AttributeValue == (int)curNumerNode.NumberVal) 
                                {
                                    return new BoolNode(true);
                                }
                            break;
                        }
                    break;
                }
            break;
        }
        return new BoolNode(false); 
    }

    ASTNode _unit_behavior_attr_value(List<ASTNode> args,Context context)
    {
        args = CoreFunction.EvalArgs(args, context);
        Unit unit = (Unit)((ObjectNode)args[0]).Val;
        string behaviorName = ((StringNode)args[1]).Val;
        BehaviorAttribute behaviorAttr = (BehaviorAttribute)unit.GetBehavior(behaviorName);
        if (behaviorAttr.AttributeValue is int)
        {
            return new NumberNode(behaviorAttr.AttributeValue, NumberNode.NumberType.INT);
        }
        return null;
    }

    ASTNode _Create_Starting_Unit(List<ASTNode> args,Context context)
    {
        #region
        /*
        List<ASTNode> newArgs  = CoreFunction.EvalArgs(args, context);
        ObjectNode readyNode = (ObjectNode)newArgs[0];
        List<ReadRoomPlayer> readyPlayers = (List<ReadRoomPlayer>)readyNode.Val;
        GameScene curScene = Game.Scene.Cur<GameScene>();

        readyPlayers.ForEach((player) =>
        {
            GamePlayer newPlayer = new GamePlayer(player);
            newPlayer.MainUnit = UnitManager.CreateUnit(player.SelectSpriteID,newPlayer.UserId.ToString(),curScene.UnitG.transform);
            curScene.Players[newPlayer.Account] = newPlayer;
            newPlayer.MainUnit.GamePlayer = newPlayer;
            if (newPlayer.Account == Game.Model.Get<PlayerModel>().Account)
            {
                curScene.LocalPlayer = newPlayer;
            }
            newPlayer.MainUnit.transform.localPosition = new Vector3(1,1.5f,0);
        });*/
        #endregion
        return null;
    }

    ASTNode _revive_unit(List<ASTNode> args,Context context)
    {
        args = CoreFunction.EvalArgs(args,context);
        Unit curUnit = (Unit)((ObjectNode)args[0]).Val;
        curUnit.IsDie = false;
        curUnit.HP = curUnit.MaxHP;
        curUnit.CallEvent("unit-revive", null);
        return null;
    }

    ASTNode _create_actor(List<ASTNode> args, Context context)
    {
        List<ASTNode> newArgs =  CoreFunction.EvalArgs(args,context);
        Actor curActor = (Actor)(((ObjectNode)newArgs[0]).Val);
        curActor.Show();
        return null;
    }

    ASTNode _play_anim(List<ASTNode> args, Context context)
    {
        List<ASTNode> newArgs = CoreFunction.EvalArgs(args, context);
        Actor actor = (Actor)((ObjectNode)newArgs[0]).Val;
        Animation anim = actor.ActorGameObject.GetComponent<Animation>();
        string animName = ((StringNode)newArgs[1]).Val;
        if (newArgs.Count == 3)
        {
            anim[animName].speed = (float)((NumberNode)newArgs[2]).NumberVal;
        }
        anim.Play(animName);
        return null;
    }

    ASTNode _play_anim_fade(List<ASTNode> args, Context context)
    {
        List<ASTNode> newArgs = CoreFunction.EvalArgs(args, context);
        Actor actor = (Actor)((ObjectNode)newArgs[0]).Val;
        Animation anim = actor.ActorGameObject.GetComponent<Animation>();
        string animName = ((StringNode)newArgs[1]).Val; 
        if (newArgs.Count == 3)
        {
            anim[animName].speed = (float)((NumberNode)newArgs[2]).NumberVal;
        }
        anim.CrossFade(animName);
        return null;
    }


    ASTNode _opt_unit_attr(List<ASTNode> args,Context context)
    {
        List<ASTNode> newArgs = CoreFunction.EvalArgs(args,context);
        Unit curUnit = (Unit)((ObjectNode)newArgs[0]).Val;
        string attrKey = ((KeywordNode)newArgs[1]).Val;
        switch (attrKey)
        {
            case ":HP":
               NumberNode newValue= (NumberNode)((IFunction)newArgs[2]).Exec(new List<ASTNode>() {new NumberNode(curUnit.HP, NumberNode.NumberType.INT),newArgs[3]},context);
               curUnit.HP = (int)newValue.NumberVal;
                //((FunctionNode)newArgs).Exec(new NumberNode(),context);
            break;
        }
        return null;
    }
    ASTNode _unit_all(List<ASTNode> args,Context context)
    {
        VectorNode vecNode = new VectorNode();
        vecNode.nodes = new ASTNode[UnitManager.Units.Count];
        int i = 0;
        foreach (KeyValuePair<long,Unit> UnitKV in UnitManager.Units)
        {
            vecNode.nodes[i] = new ObjectNode(UnitKV.Value);
           i++;
        }
        return vecNode;
    }
}
